package com.zoke.monitor;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import com.zoke.library.util.MessageHandlerList;
import com.zoke.library.util.StatusBarUtil;
import com.zoke.monitor.adapter.TabBottom;
import com.zoke.monitor.adapter.TabBottomAdapter;
import com.zoke.monitor.fragment.MainFragment;
import com.zoke.monitor.fragment.MineFragment;
import com.zoke.monitor.fragment.MonitorFragment;
import com.zoke.monitor.fragment.NFCFragment;
import com.zoke.monitor.view.FixedIndicatorView;
import com.zoke.monitor.view.Indicator;

import org.xutils.common.util.LogUtil;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.ViewInject;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {
    @ViewInject(R.id.bottom_bar)
    private FixedIndicatorView bottom_bar;
    @ViewInject(R.id.toolbar)
    private Toolbar toolbar;
    @ViewInject(R.id.title)
    private TextView title;

    private List<TabBottom> mList = new ArrayList<>();
    private TabBottomAdapter mTabBottomAdapter;

    private List<Fragment> mTabFragments = new ArrayList<>();
    private int currentTab;


    //NFC相关的数据
    private NfcAdapter mAdapter;
    private PendingIntent mPendingIntent;
    private NdefMessage mNdefPushMessage;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        resolveIntent(getIntent());
        StatusBarUtil.setColor(this, getResources().getColor(R.color.colorPrimary));
        initTabContent();
        mAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mAdapter == null) {
//            showMessage(R.string.error, R.string.no_nfc);
//            finish();
            //该手机不支持NFC
            MessageHandlerList.sendMessage(NFCFragment.class, 101);
            return;
        }

        mPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        mNdefPushMessage = new NdefMessage(new NdefRecord[]{newTextRecord(
                "Message from NFC Reader :-)", Locale.ENGLISH, true)});
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mAdapter != null) {
            if (!mAdapter.isEnabled()) {
                showWirelessSettingsDialog();
            }
            mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
            mAdapter.enableForegroundNdefPush(this, mNdefPushMessage);
        }
    }

    private void showWirelessSettingsDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.nfc_disabled);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
                startActivity(intent);
            }
        });
        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                finish();
            }
        });
        builder.create().show();
        return;
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAdapter != null) {
            mAdapter.disableForegroundDispatch(this);
            mAdapter.disableForegroundNdefPush(this);
        }
    }

    private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));

        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        byte[] textBytes = text.getBytes(utfEncoding);

        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char) (utfBit + langBytes.length);

        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        data[0] = (byte) status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);

        return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
    }


    private void resolveIntent(Intent intent) {
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            NdefMessage[] msgs;
            if (rawMsgs != null) {
                msgs = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    msgs[i] = (NdefMessage) rawMsgs[i];
                }
            } else {
                // Unknown tag type
                byte[] empty = new byte[0];
                byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
                Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                byte[] payload = dumpTagData(tag).getBytes();
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
                NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
                msgs = new NdefMessage[]{msg};
            }
            bottom_bar.setCurrentItem(2);
            showTab(2);
            MessageHandlerList.sendMessage(NFCFragment.class, 100, msgs);
        }
    }


    private void showTab(int select) {
        try {
            if (currentTab != select) {
                switch (select) {
                    case 0:
                        title.setText(getResources().getString(R.string.main));
                        break;
                    case 1:
                        title.setText(getResources().getString(R.string.monitor));
                        break;
                    case 2:
                        title.setText(getResources().getString(R.string.nfc));
                        break;
                    case 3:
                        title.setText(getResources().getString(R.string.mine));
                        break;
                }
                FragmentTransaction trx = getSupportFragmentManager()
                        .beginTransaction();
                trx.hide(mTabFragments.get(currentTab));
                if (!mTabFragments.get(select).isAdded()) {
                    trx.add(R.id.content, mTabFragments.get(select));
                }
                trx.show(mTabFragments.get(select)).commit();
            }
            currentTab = select;
            if (android.os.Build.VERSION.SDK_INT >= 11)
                MainActivity.this.getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
            invalidateOptionsMenu();
        } catch (Exception e) {
            LogUtil.e(e.toString());
        }
    }

    private String dumpTagData(Parcelable p) {
        StringBuilder sb = new StringBuilder();
        Tag tag = (Tag) p;
        byte[] id = tag.getId();
        sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
        sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
        sb.append("ID (reversed): ").append(getReversed(id)).append("\n");

        String prefix = "android.nfc.tech.";
        sb.append("Technologies: ");
        for (String tech : tag.getTechList()) {
            sb.append(tech.substring(prefix.length()));
            sb.append(", ");
        }
        sb.delete(sb.length() - 2, sb.length());
        for (String tech : tag.getTechList()) {
            if (tech.equals(MifareClassic.class.getName())) {
                sb.append('\n');
                MifareClassic mifareTag = MifareClassic.get(tag);
                String type = "Unknown";
                switch (mifareTag.getType()) {
                    case MifareClassic.TYPE_CLASSIC:
                        type = "Classic";
                        break;
                    case MifareClassic.TYPE_PLUS:
                        type = "Plus";
                        break;
                    case MifareClassic.TYPE_PRO:
                        type = "Pro";
                        break;
                }
                sb.append("Mifare Classic type: ");
                sb.append(type);
                sb.append('\n');

                sb.append("Mifare size: ");
                sb.append(mifareTag.getSize() + " bytes");
                sb.append('\n');

                sb.append("Mifare sectors: ");
                sb.append(mifareTag.getSectorCount());
                sb.append('\n');

                sb.append("Mifare blocks: ");
                sb.append(mifareTag.getBlockCount());
            }

            if (tech.equals(MifareUltralight.class.getName())) {
                sb.append('\n');
                MifareUltralight mifareUlTag = MifareUltralight.get(tag);
                String type = "Unknown";
                switch (mifareUlTag.getType()) {
                    case MifareUltralight.TYPE_ULTRALIGHT:
                        type = "Ultralight";
                        break;
                    case MifareUltralight.TYPE_ULTRALIGHT_C:
                        type = "Ultralight C";
                        break;
                }
                sb.append("Mifare Ultralight type: ");
                sb.append(type);
            }
        }

        return sb.toString();
    }


    private String getHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = bytes.length - 1; i >= 0; --i) {
            int b = bytes[i] & 0xff;
            if (b < 0x10)
                sb.append('0');
            sb.append(Integer.toHexString(b));
            if (i > 0) {
                sb.append(" ");
            }
        }
        return sb.toString();
    }

    private long getDec(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = 0; i < bytes.length; ++i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    private long getReversed(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = bytes.length - 1; i >= 0; --i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    private void initTabContent() {
        toolbar.setTitle("");
        title.setText(getResources().getString(R.string.main));
        toolbar.setTitleTextColor(getResources().getColor(R.color.white));
        setSupportActionBar(toolbar);
        initTabDatas();
        mTabBottomAdapter = new TabBottomAdapter(mList, this);
        bottom_bar.setAdapter(mTabBottomAdapter);
        bottom_bar.setOnItemSelectListener(new Indicator.OnItemSelectedListener() {
            @Override
            public void onItemSelected(View selectItemView, int select, int preSelect) {
                showTab(select);
            }
        });
        mTabFragments.add(new MainFragment());
        mTabFragments.add(new MonitorFragment());
        mTabFragments.add(new NFCFragment());
        mTabFragments.add(new MineFragment());
        getSupportFragmentManager().beginTransaction()
                .add(R.id.content, mTabFragments.get(0), mTabFragments.get(0).getClass().getName())
                .add(R.id.content, mTabFragments.get(1), mTabFragments.get(1).getClass().getName())
                .add(R.id.content, mTabFragments.get(2), mTabFragments.get(2).getClass().getName())
                .add(R.id.content, mTabFragments.get(3), mTabFragments.get(3).getClass().getName())
                .hide(mTabFragments.get(1)).hide(mTabFragments.get(2))
                .hide(mTabFragments.get(3)).show(mTabFragments.get(0)).commit();
    }


    /**
     * 设置底部tab文字和图标
     */
    private void initTabDatas() {
        //发现列表
        TabBottom find = new TabBottom();
        find.iconRes = R.drawable.tab_find_selector;
        find.tabName = getResources().getString(R.string.main);
        TabBottom top = new TabBottom();
        top.iconRes = R.drawable.main_selector;
        top.tabName = getResources().getString(R.string.monitor);
        TabBottom msg = new TabBottom();
        msg.iconRes = R.drawable.order_selector;
        msg.tabName = getResources().getString(R.string.nfc);
        TabBottom my = new TabBottom();
        my.iconRes = R.drawable.mine_selector;
        my.tabName = getResources().getString(R.string.mine);
        mList.add(find);
        mList.add(top);
        mList.add(msg);
        mList.add(my);
    }

    @Override
    public void onNewIntent(Intent intent) {
        setIntent(intent);
        resolveIntent(intent);
    }

}
